#include <my_head.h>

// 不可被取消--取消不了
void *task_func1(void *arg){
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); // 不可被取消
    while(1){
        printf("我是子线程:[%ld]\n", pthread_self());
        sleep(1);
    }
}

// 可被取消，立即取消 --可以取消
void *task_func2(void *arg){
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); // 可被取消
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // 立即取消
    while(1){
        printf("我是子线程:[%ld]\n", pthread_self());
        sleep(1);
    }
}

// 可被取消，延时取消，有能作为取消点的函数 --可以取消
void *task_func3(void *arg){
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); // 可被取消
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); // 延时取消
    while(1){
        printf("我是子线程:[%ld]\n", pthread_self()); // 能作为取消点的函数
        sleep(1); // 能作为取消点的函数
    }
}

// 可被取消，延时取消，没有能作为取消点的函数 --取消不了
// 这种情况不常见 因为实际开发时 线程处理函数中都或多或少的会调用一些能作为取消点的函数
void *task_func4(void *arg){
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); // 可被取消
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); // 延时取消
    int x = 10;
    while(1){
        x = 10;
    }
}

// 可被取消，立即取消，没有能作为取消点的函数 --可以取消
void *task_func5(void *arg){
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); // 可被取消
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // 立即取消
    int x = 10;
    while(1){
        x = 10;
    }
}

int main(int argc, const char *argv[]){
    pthread_t tid1 = 0, tid2 = 0, tid3 = 0, tid4 = 0, tid5 = 0;
    int ret = 0;
    if(0 != (ret = pthread_create(&tid1, NULL, task_func1, NULL))){
        printf("pthread_create error : [%d] [%s]\n", ret, strerror(ret));
        exit(EXIT_FAILURE);
    }
    if(0 != (ret = pthread_create(&tid2, NULL, task_func2, NULL))){
        printf("pthread_create error : [%d] [%s]\n", ret, strerror(ret));
        exit(EXIT_FAILURE);
    }
    if(0 != (ret = pthread_create(&tid3, NULL, task_func3, NULL))){
        printf("pthread_create error : [%d] [%s]\n", ret, strerror(ret));
        exit(EXIT_FAILURE);
    }
    if(0 != (ret = pthread_create(&tid4, NULL, task_func4, NULL))){
        printf("pthread_create error : [%d] [%s]\n", ret, strerror(ret));
        exit(EXIT_FAILURE);
    }
    if(0 != (ret = pthread_create(&tid5, NULL, task_func5, NULL))){
        printf("pthread_create error : [%d] [%s]\n", ret, strerror(ret));
        exit(EXIT_FAILURE);
    }
    sleep(5);
    pthread_cancel(tid1);
    pthread_cancel(tid2);
    pthread_cancel(tid3);
    pthread_cancel(tid4);
    pthread_cancel(tid5);
    printf("我是主线程:[%ld] 已经发完取消请求了\n", pthread_self());

    // 阻塞等子线程结束 回收资源
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    pthread_join(tid3, NULL);
    pthread_join(tid4, NULL);
    pthread_join(tid5, NULL);

    return 0;
}